﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StateSharp
{
    /// <summary>
    /// 表示状态上下文。
    /// </summary>
    public class Context<TType>
    {
        private State<TType> m_currentState; // 当前状态实例。
        /// <summary>
        /// 当前状态。
        /// </summary>
        public State<TType> CurrentState
        {
            get { return m_currentState; }
            private set { m_currentState = value; }
        }
        private State<TType> m_lastState; // 上一状态。
        /// <summary>
        /// 上一状态。
        /// </summary>
        public State<TType> LastState
        {
            get { return m_lastState; } 
        }
        /// <summary>
        /// 状态上下文构造方法。
        /// </summary>
        public Context()
        {
        }
        /// <summary>
        /// 初始状态赋值。
        /// </summary>
        /// <param name="state"></param>
        public void InitState(State<TType> state)
        {
            m_currentState = state;
        }
        /// <summary>
        /// 启动状态上下文。
        /// </summary>
        public void Start(TType transition = default(TType))
        {
            if (m_currentState.Exec != null)
            {
                m_currentState.Exec.Invoke(transition);
            }
        }
        /// <summary>
        /// 执行转换。
        /// </summary>
        /// <param name="type"></param>
        public void DoTransition(TType type)
        {
            State<TType> state = m_currentState.DoTransition(type);
            if (state != null)
            {
                if (m_currentState != state)
                {
                    if (m_currentState.Exit != null)
                    {
                        m_currentState.Exit.Invoke(type);
                    }
                    if (state.Enter != null) // 委托不为空时，执行。
                    {
                        state.Enter.Invoke(type);
                    } 
                }
                m_lastState = m_currentState; // 上一状态。
                m_currentState = state;
                if (state.Exec != null) // 委托不为空时，执行。
                {
                    state.Exec.Invoke(type);
                } 
            }
        }
    }
}
